package com.sudoctor.dao.impl;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.Map;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import com.sudoctor.dao.GenericDao;

public abstract class GenericDaoImpl< T > extends JdbcDaoSupport implements GenericDao< T >
{
	
	private Class<T> type;
	private JdbcTemplate jdbcTemplate;

    public GenericDaoImpl() {
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        type = (Class) pt.getActualTypeArguments()[0];
    }
    
    public long countAll(final Map<String, Object> params) {

        final StringBuffer queryString = new StringBuffer(
                "SELECT count(o) from ");

        queryString.append(type.getSimpleName()).append(" o ");
        queryString.append(this.getQueryClauses(params, null));

       // final Query query = this.em.createQuery(queryString.toString());

       // return (Long) query.getSingleResult();
        
        return 0;

    }

	@Override
	public T create(T t)
	{
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> void delete(T clase)
	{
		String name = clase.getClass().getName();
		Class claseLocal = clase.getClass();
		Field[] dtoFields = claseLocal.getDeclaredFields();
		
		for (Field field : dtoFields)
		{
			if(field.getName().trim().equals("id"))
			{
				String delQuery = "delete from users where id = ?";
				StringBuffer sb = new StringBuffer();
				sb.append("delete from ");
				sb.append(name);
				sb.append(" where id = ");
				//sb.append(field.get(field));
				int count = jdbcTemplate.update(delQuery, new Object[] {  });
				if(count!=0)
				System.out.println("User deleted successfully.");
				else
				System.out.println("Couldn't delete user with given id as it doesn't exist");
			}
		}
		
		
	}


	@Override
	public T update(T t)
	{
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public T find(String id, String entidad)
	{
		// TODO Auto-generated method stub
		return null;
	}
	
	/**
	 * 
	 * @param params.- Para las condiciones de la consulta. Map <Campo de la base de datos,Tipo de dato>
	 * @param orderParams.-Para el order by de la consulta. Map<Campo de la base de datos,>
	 * @return
	 */
	private String getQueryClauses(final Map<String, Object> params, final Map<String, Object> orderParams) {
		final StringBuffer queryString = new StringBuffer();
		if ((params != null) && !params.isEmpty()) {
			
			queryString.append(" where ");
			
			for (final Iterator<Map.Entry<String, Object>>   it = params.entrySet().iterator();      it.hasNext();    ) {
				
				final Map.Entry<String, Object> entry = it.next();
				
				if (entry.getValue() instanceof Boolean) {
					queryString.append(entry.getKey()).append(" is ")
							.append(entry.getValue()).append(" ");
				} else {
					if (entry.getValue() instanceof Number) {
						queryString.append(entry.getKey()).append(" = ")
								.append(entry.getValue());
					} else {
						// string equality
						queryString.append(entry.getKey()).append(" = '")
								.append(entry.getValue()).append("'");
					}
				}
				if (it.hasNext()) {
					queryString.append(" and ");
				}
			}
		}
		if ((orderParams != null) && !orderParams.isEmpty()) {
			queryString.append(" order by ");
			for (final Iterator<Map.Entry<String, Object> > it = orderParams.entrySet().iterator(); it.hasNext();) {
				
				
				final Map.Entry<String, Object> entry = it.next();
				
				queryString.append(entry.getKey()).append(" ");
				if (entry.getValue() != null) {
					queryString.append(entry.getValue());
				}
				if (it.hasNext()) {
					queryString.append(", ");
				}
				
				
			}
		}
		return queryString.toString();
	}


}
